package com.apes.fn.scm.appScan;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.MapUtil;
import com.apes.pi.service.PiManager;
import com.apes.scm.account.account.model.Stock;
import com.apes.scm.account.account.repository.StockRepository;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import com.apes.scm.masterdata.product.model.Product;
import com.apes.scm.masterdata.product.repository.ProductRepository;
import com.apes.scm.masterdata.stock.model.Location;
import com.apes.scm.masterdata.stock.repository.LocationRepository;
import com.apes.scm.stock.inventory.model.InventoryMark;
import com.apes.scm.stock.inventory.repository.InventoryMarkRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 调用服务
 */
@Service("appScanService")
public class AppScanService extends DomainService {

    @Autowired
    private Collection<Template> templates;
    @Autowired
    private PiManager piManager;
    @Autowired
    private ProductRepository productRepository;

    private static volatile Map<String, Template> templateMap = new HashMap<>();

    private Template getTemplate(String type) {
        if (templateMap.isEmpty()) {
            synchronized (templateMap) {
                if (templateMap.isEmpty()) {
                    for (Template template : templates) {
                        for (String identify : template.identifys()) {
                            templateMap.put(identify, template);
                        }
                    }
                }
            }
        }
        if (!templateMap.containsKey(type)) throw new RuntimeException("未找到对应模板,请检查！");
        return templateMap.get(type);
    }

    public String getOrder(SimpleRequest request) {
        String id = request.get("id");

        JSONObject result = new JSONObject();
        result.put("msg", "接囗调用成功,日志上传到服务器");
        result.put("obj", getTemplate(request.get("identify")).getOrder(id).toJSONString());
        result.put("success", true);
        return result.toJSONString();
    }

    public String getOrderLists(SimpleRequest request) {
        JSONObject json = request.getJO();

        String origin = json.getString("origin");
        if (origin == null) origin = json.getString("FWDH");


        JSONObject result = new JSONObject();
        /*  执行查询之前 */
        if (AppScanEnum.QRY_PJGHDLYMX.getCode().equals(request.get("interfaceMethod"))) {
            // 配件归还单领用明细
            origin = json.getString("LYDH");
        }

        /*  执行查询  */
        String orderString = getTemplate(request.get("identify")).getOrderLists(request, origin).toJSONString();
        result.put("obj", orderString);

        /*  执行查询之后 */
        if (AppScanEnum.QRY_PJGHD.getCode().equals(request.get("interfaceMethod"))) {
            JSONObject dhList = new JSONObject();
            dhList.put("dhList", orderString);
            result.put("obj", dhList.toJSONString());
        }

        result.put("success", true);
        result.put("msg", "接囗调用成功,日志上传到服务器");
        return result.toJSONString();
    }


    public String begin(SimpleRequest request) {
        String id = request.get("CRKDH");
        getTemplate(request.get("LYDJLX")).begin(id, request.get("CZYID"));
        return returnInventoryMark("[]", "接囗调用成功,日志上传到服务器", true);
    }

    public String cancel(SimpleRequest request) {
        String id = request.get("CRKDH");

        getTemplate(request.get("LYDJLX")).cancel(id, request.get("CZYID"));
        return returnInventoryMark("[]", "接囗调用成功,日志上传到服务器", true);
    }

    public String submit(SimpleRequest request) {
        String GXBSID = request.get("GXBSID");

        // 执行控制
        InventoryMark inventoryMark = SpringManager.getBean(InventoryMarkRepository.class).findOne(GXBSID);
        if (inventoryMark == null) {
            inventoryMark = new InventoryMark();
            inventoryMark.setId(GXBSID);
            inventoryMark.setState(0);
            saveInventoryMark(inventoryMark);
        } else {
            if (inventoryMark.getState() == 0) {
                return returnInventoryMark(inventoryMark, "单据执行中，请稍等。", false);
            } else if (inventoryMark.getState() == 1) {
                //return returnInventoryMark(inventoryMark, "单据执行错误。", false);
            } else if (inventoryMark.getState() == 2) {
                return returnInventoryMark(inventoryMark, "单据执行成功。", true);
            }
        }

        try {
            getTemplate(request.get("LYDJLX")).submit(request);
        } catch (Exception e) {
            inventoryMark = SpringManager.getBean(InventoryMarkRepository.class).findOne(GXBSID);
            inventoryMark.setState(1);
            saveInventoryMark(inventoryMark);
            throw new RuntimeException(e.getMessage());
        }
        inventoryMark = SpringManager.getBean(InventoryMarkRepository.class).findOne(GXBSID);
        inventoryMark.setState(2);
        saveInventoryMark(inventoryMark);
        return returnInventoryMark("[]", "接囗调用成功,日志上传到服务器", true);
    }

    private String returnInventoryMark(Object object, String msg, boolean flag) {
        JSONObject result = new JSONObject();
        result.put("msg", msg);
        result.put("obj", MapUtil.mapped(object));
        result.put("success", flag);
        return result.toJSONString();
    }

    private void saveInventoryMark(InventoryMark mark) {
        SpringManager.getBean(DomainService.class).sendAynEvent("event:scm.inventoryMarkService.save", MapUtil.mapped(mark));
    }

    /**
     * 查询仓库库区
     *
     * @param request
     * @return
     */
    public String qryLocation(SimpleRequest request) {
        JSONObject jsonObject = request.getJO();

        JSONObject result = new JSONObject();
        result.put("msg", "接囗调用成功,日志上传到服务器");
        result.put("success", true);

        List<Location> locations = SpringManager.getBean(LocationRepository.class).findAll(JpaDsl.toCriteriaByEq("depot.dept.id", jsonObject.getString("DDID")));
        if (locations.size() == 0) {
            result.put("obj", "[]");
        } else {
            String usageId = jsonObject.getString("CKLX");
            JSONArray resultArray;
            JSONArray array = new JSONArray();
            locations.forEach(location -> {
                JSONObject json = new JSONObject();
                json.put("CKKQID", location.getId());
                json.put("CKKQMC", location.getName());
                json.put("CKID", location.getDepot().getDept().getId());
                json.put("CKMC", location.getDepot().getDept().getName());
                json.put("KQID", location.getUsage().getId());
                json.put("KQMC", location.getUsage().getName());
                json.put("GSID", location.getCompany().getId());
                json.put("GSMC", location.getCompany().getName());
                json.put("DDID", location.getDepot().getDept().getId());
                json.put("DDMC", location.getDepot().getDept().getName());
                array.add(json);
            });
            resultArray = array;

            // 耗材领用单自取正常库
            if (!StringUtils.isEmpty(usageId)) {
                List list = array.stream().filter(item -> usageId.equals(((JSONObject) item).getString("KQID"))).collect(Collectors.toList());
                resultArray = JSONObject.parseArray(list.toString());
            }
            result.put("obj", resultArray.toJSONString());
        }
        return result.toJSONString();
    }

    /**
     * 耗材领用单查询商品
     *
     * @param request {"CKKQID": "", "SPID": ""}
     * @return Product
     */
    public String qrySP(SimpleRequest request) {

        JSONObject result = new JSONObject();
        result.put("msg", "接囗调用成功,日志上传到服务器");
        result.put("success", true);

        String productId = request.get("SPID");
        Page<Product> productPage = productRepository.findByIdOrBarcodeOrName(productId, PageRequest.of(0, 30));
        List<Product> products = productPage.getContent();
        if (products.size() == 0) {
            result.put("obj", "[]");
        } else if (products.size() > 1) {
            JSONArray array = new JSONArray();
            products.forEach(product -> {
                JSONObject json = new JSONObject();
                json.put("SPID", product.getId());
                json.put("SPMC", product.getName());
                json.put("JLDW", product.getUom().getName());
                json.put("HSBL", product.getUom().getFactor());
                json.put("GYSTM", product.getBarcode());
                json.put("DJSL", 0);
                json.put("SMJS", 0);
                array.add(json);
            });
            result.put("obj", array.toJSONString());
        } else {
            Product product = products.get(0);
            if (!product.isFreeSuppliesValid())
                throw new RuntimeException("该商品非免费耗材，不能操作耗材领用，商品编码：" + product.getId());

            List<Stock> stocks = SpringManager.getBean(StockRepository.class).findStockByLocationAndProduct(request.get("CKKQID"), product.getId());
            if (stocks.size() == 0) throw new RuntimeException("该商品在当前仓库无库存，不能操作耗材领用，商品编码：" + product.getId());

            JSONArray array = new JSONArray();
            stocks.forEach(stock -> {
                JSONObject json = new JSONObject();
                json.put("SPID", stock.getProduct().getId());
                json.put("SPMC", stock.getProduct().getName());
                json.put("JLDW", stock.getProduct().getUom().getName());
                json.put("HSBL", stock.getProduct().getUom().getFactor());
                json.put("GYSTM", stock.getProduct().getBarcode());
                json.put("DJSL", 0);
                json.put("SMJS", 0);
                array.add(json);
            });
            result.put("obj", array.toJSONString());
        }
        return result.toJSONString();
    }

    /**
     * 查询商品信息
     *
     * @param request
     * @return
     */
    public String qrySPXX(SimpleRequest request) {
        JSONObject json = request.getJO();
        String productId = json.getString("SPID");

        List<Product> products;
        if (json.containsKey("KEY") && "PD".equals(json.getString("KEY"))) {
            // 盘点查询
            Page<Product> productPage = productRepository.findByIdOrBarcodeForScan(productId, productId, PageRequest.of(0, 2));
            products = productPage.getContent();
        } else {

            // 兼容之前的写法
            if (Pattern.matches("[\\u4e00-\\u9fa5]*", productId)   // 匹配中文
                    || (json.containsKey("CKKQID") && json.containsKey("DDID")) || !json.containsKey("DDID") ) {
                // 输入中文的情况 或者  弹出框查询的情况
                Page<Product> productPage = productRepository.findByIdOrBarcodeOrName(productId, PageRequest.of(0, 30));
                products = productPage.getContent();
            } else {
                Page<Product> productPage = productRepository.findByIdOrBarcodeForScan(productId, productId, PageRequest.of(0, 2));
                products = productPage.getContent();
            }
        }

        // 封装数据
        JSONObject result = new JSONObject();
        if (products.size() == 0) {
            result.put("obj", "[]");
        } else {
            JSONArray array = new JSONArray();
            products.forEach(product -> {
                JSONObject jo = new JSONObject();
                jo.put("SPID", product.getId());
                jo.put("SPMC", product.getName());
                jo.put("JLDW", product.getUom().getName());
                jo.put("HSBL", product.getUom().getFactor());
                jo.put("GYSTM", product.getBarcode());
                jo.put("DJSL", 0);
                jo.put("SMJS", 0);
                array.add(jo);
            });
            result.put("obj", array.toJSONString());
        }
        result.put("msg", "接囗调用成功,日志上传到服务器");
        result.put("success", true);
        result.put("bgo", false);
        return result.toJSONString();
    }

    public String queryZCKP(SimpleRequest request) {
        return piManager.synErp(AppScanEnum.QRY_ZCKP.getCode(), request.getJO()).toJSONString();
    }

    /**
     * 根据车牌过滤配件领用单
     */
    public JSONArray findByCar(SimpleRequest request) {
        JSONObject jo = request.getJO();

        String obj = getOrderLists(request);
        JSONObject jsonObject = JSONObject.parseObject(obj);
        JSONArray jsonArray = jsonObject.getJSONObject("obj").getJSONArray("dhList");
        String cp = request.get("CP").toString();

        JSONObject data = new JSONObject();
        data.put("DDID", jo.getString("deptId"));
        data.put("BDQXID", jo.getString("localPermitId"));
        data.put("LYDJLX", jo.getString("identify"));
        data.put("interfaceMethod", "ipmTmcrkForPhoneService.qryLYMX");

        JSONArray result = new JSONArray();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject o = jsonArray.getJSONObject(i);
            if (cp.equals(o.get("CPHM").toString())) {
                data.put("LYDH", o.getString("LYDH"));
                String invoke = this.invoke("fn.appScan.getOrderLists", data);
                JSONObject object = JSONObject.parseObject(invoke);
                o.put("obj", object.getJSONArray("obj"));
                result.add(o);
            }
        }
        return result;
    }

}
